#include "weldingalgorithmmanager.h"
#include "Alg/weldinginitializationworker.h"
#include "qapplication.h"
#include <QElapsedTimer>
#include <QThread>
#include <QDebug>
#include <exception>
#include <QCoreApplication>

namespace Alg {

// WeldingAlgorithmManager 实现
WeldingAlgorithmManager::WeldingAlgorithmManager()
    : m_signal(0)
    , m_resultReceived(false)
    , m_threadsRunning(false)
    , m_initialized(false)
{
}

WeldingAlgorithmManager::~WeldingAlgorithmManager()
{
    // 清理资源
}

WeldingAlgorithmManager& WeldingAlgorithmManager::instance()
{
    static WeldingAlgorithmManager instance;
    return instance;
}



bool WeldingAlgorithmManager::initialize()
{
    std::lock_guard<std::mutex> lock(m_mutex);
    if (m_initialized || m_initializing)
        return false;

    m_initializing = true;

    WeldingInitializationWorker* worker = new WeldingInitializationWorker();
    worker->moveToThread(&m_initThread);

    // 线程结束时自动销毁 worker
    QObject::connect(&m_initThread, &QThread::finished,
                     worker, &QObject::deleteLater);

    QObject::connect(worker, &WeldingInitializationWorker::initializationFinished,
                     worker,
                     [this](bool success)
                     {
                         // 把结果异步抛回主线程
                         QMetaObject::invokeMethod(
                             QCoreApplication::instance(),
                             [=]()
                             {
                                 handleInitResult(success);
                             },
                             Qt::QueuedConnection);
                     });

    m_initThread.start();
    QMetaObject::invokeMethod(worker, "doInitialize", Qt::QueuedConnection);
    return true;
}

void WeldingAlgorithmManager::handleInitResult(bool success)
{
    if (success)
    {
        qDebug() << "Welding algorithm initialized, starting worker threads";
        startWorkerThreads();
        m_initialized = true;
    }
    else
    {
        qDebug() << "Welding algorithm initialization failed";
    }

    m_initializing = false;
    m_initThread.quit();
    m_initThread.wait();
}

void WeldingAlgorithmManager::startWorkerThreads()
{
    // 启动生产者线程
    m_producerThread = std::thread([this]() {
        Obj<WeldingDetector>::GetInstance()->ProducerFunc();
    });

    // 启动消费者线程
    for (int i = 0; i < WORKNUM; ++i) {
        m_consumerThreads[i] = std::thread([this, i]() {
            Obj<WeldingDetector>::GetInstance()->ConsumerFunc(i);
        });
    }

    // 启动报告线程
    m_reportThread = std::thread([this]() {
        Obj<WeldingDetector>::GetInstance()->Report([this](WeldingResult result) {
            // 将结果通过Qt信号槽机制传递到主线程
            QMetaObject::invokeMethod(QApplication::instance(), [this, result]() {
                processingCallback(std::move(result));
            }, Qt::QueuedConnection);
        });
    });

    // 设置线程分离，避免资源泄露
    m_producerThread.detach();
    for (int i = 0; i < WORKNUM; ++i) {
        m_consumerThreads[i].detach();
    }
    m_reportThread.detach();
}

void WeldingAlgorithmManager::stopWorkerThreads()
{

}

void WeldingAlgorithmManager::setResultCallback(ResultCallback callback)
{
    std::lock_guard<std::mutex> lock(m_mutex);
    m_resultCallback = std::move(callback);
}

void WeldingAlgorithmManager::processingCallback(WeldingResult result)
{
    std::lock_guard<std::mutex> lock(m_mutex);
    m_lastResult = result;
    // 调用回调函数
    if (m_resultCallback) {
        m_resultCallback(result);
    }
}

void WeldingAlgorithmManager::processImages(const std::vector<cv::Mat>& images,int id)
{
    std::unique_lock<std::mutex> lock(m_mutex);

    if (!m_initialized) {
        qWarning() << "Algorithm not initialized";
        m_signal = -1;
        return;
    }

    if (images.size() != 4) {
        qWarning() << "Expected 4 images, got" << images.size();
        m_signal = -1;
        return;
    }
    // 转换图像格式
    std::vector<cv::Mat> inputImages;
    for (const cv::Mat& img : images) {
        inputImages.push_back(img.clone());
    }

    // 设置输入图像
    Obj<WeldingDetector>::GetInstance()->SetIuputImages(inputImages, id);
}

void WeldingAlgorithmManager::processImages(const cv::Mat &image, int id)
{
    std::unique_lock<std::mutex> lock(m_mutex);

    if (!m_initialized) {
        qWarning() << "Algorithm not initialized";
        m_signal = -1;
        return;
    }

    // 转换图像格式
    std::vector<cv::Mat> inputImages;
    inputImages.push_back(image.clone());
    qWarning() << "WeldingAlgorithmManager::processImages(const cv::Mat &image, int id):"<<id;
    // 设置输入图像
    Obj<WeldingDetector>::GetInstance()->SetIuputImagessignal(inputImages[0], id);
}


int WeldingAlgorithmManager::getSignal() const
{
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_signal;
}

cv::Mat WeldingAlgorithmManager::getFusionResult() const
{
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_fusionResult.clone();
}

cv::Mat WeldingAlgorithmManager::getDetectionResult() const
{
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_detectionResult.clone();
}

WeldingResult WeldingAlgorithmManager::getTableData() const
{
    std::lock_guard<std::mutex> lock(m_mutex);
    return m_lastResult;
}

// 对外接口函数实现
void CameraFunc(const std::vector<cv::Mat>& images, int id)
{
    WeldingAlgorithmManager::instance().processImages(images,id);
}

int GetSignal()
{
    return WeldingAlgorithmManager::instance().getSignal();
}

cv::Mat GetFusionResult()
{
    return WeldingAlgorithmManager::instance().getFusionResult();
}

cv::Mat GetDetectionResult()
{
    return WeldingAlgorithmManager::instance().getDetectionResult();
}

WeldingResult GetTableData()
{
    return WeldingAlgorithmManager::instance().getTableData();
}

void CameraFunc(const cv::Mat &image, int id)
{
    WeldingAlgorithmManager::instance().processImages(image,id);
}

} // namespace Alg
